package com.common.service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;

import com.common.api.annontation.ServiceLog;

/**
 * @author ficus
 * spring上下文服务
 */
@Component
@Validated
@ServiceLog
public class SpringContextHolder {
	
	@Autowired
	private ApplicationContext applicationContext;
	
    @Autowired
    private ConfigurableEnvironment env;
	
	public String[] queryBeanNames() {
		return applicationContext.getBeanDefinitionNames();
	}

	public Object getBeanByName(@NotBlank String beanName) {
	   return applicationContext.getBean(beanName);
	}
	
	public <T> T getBeanByClass(@NotNull Class<T> requiredType) {
		return applicationContext.getBean(requiredType);
	}
   
	public <T> T getBeanByClass(@NotNull Class<T> requiredType,String beanName) {
		return applicationContext.getBean(beanName, requiredType);
	}
	
	public Map<String, Object> getSystemEnvironment() {
		return env.getSystemEnvironment();
	}
	
	public Map<String, Object> getSystemProperties() {
		return env.getSystemProperties();
	}
	
	public List<String> getPropertyNames() {
		List<String> result=new ArrayList<>();
		MutablePropertySources propertySources=env.getPropertySources();
		propertySources.forEach(new Consumer<PropertySource<?>>() {
			@Override
			public void accept(PropertySource<?> t) {
				if(t instanceof  MapPropertySource ) {
					MapPropertySource source=(MapPropertySource) t;
					result.addAll(source.getSource().keySet());
				}
			}
		});
		return result;
	}
	
	public Object getPropertyValue(@NotNull String paramKey) {
		String value=env.getProperty(paramKey);
		return value;
	}
	
	public ApplicationContext getApplicationContext() {
		return applicationContext;
	}
}
